package com.goldcn.user.controller;

import com.goldcn.common.consts.RestConst;
import com.goldcn.common.exception.ServiceException;
import com.goldcn.common.model.DataResult;
import com.goldcn.common.util.CommonUtils;
import com.goldcn.common.util.UuidUtils;
import com.goldcn.config.ProConstants;
import com.goldcn.interceptor.SystemContext;
import com.goldcn.user.dto.*;
import com.goldcn.user.model.*;
import com.goldcn.user.service.*;
import com.goldcn.user.vo.CompanyInfoVo;
import com.goldcn.util.*;
import com.google.common.base.Objects;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.security.Key;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by 1111 on 2016/11/11.
 */
@Api(value = "登录注册")
@RestController
@ConfigurationProperties(prefix = "sms")
public class MainController {
    private String codeUrl;
    private static Logger logger = Logger.getLogger(MainController.class);
    @Autowired
    RedisService redisService;

    @Autowired
    UserLoginService userLoginService;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    CompanyInfoService companyInfoService;

    @Autowired
    OrganizationalService organizationalService;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    CodeService codeService;

    @Autowired
    ConfigService configService;

    public void setCodeUrl(String codeUrl) {
        this.codeUrl = codeUrl;
    }


    @ApiOperation(value = "登录(type:1云管控 2供应商 3会员顾问)")
    @RequestMapping(value = "/login/{type}", method = RequestMethod.POST)
    public Object login(@PathVariable int type, @RequestBody LoginDto loginDto) throws Exception {
        if (type != 3) {
            verifyImgCode(loginDto.getUuID(), loginDto.getImgCode());//验证验证码
        }
        PrivateKey key = (PrivateKey) redisService.loadKey(loginDto.getRasId());
        byte[] en_result = RSAUtils.hexStringToBytes(loginDto.getPassWord());
        byte[] de_result = RSAUtils.decrypt(key, en_result);
        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.newStringUtf8(de_result));
        loginDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
        UserLogin userLogin = new UserLogin();
        BeanUtils.copyProperties(userLogin, loginDto);
        userLogin = userLoginService.selectForLogin(userLogin);
        if (userLogin == null) {
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }

        //修改登录表信息
        UserLogin ulForUpdate = new UserLogin();
        ulForUpdate.setId(userLogin.getId());
        ulForUpdate.setLastLoginIP(userLogin.getLoginIP());
        ulForUpdate.setLastLoginTime(userLogin.getLoginTime());
        ulForUpdate.setLoginIP(CusAccessObjectUtil.getIpAddress(request));
        ulForUpdate.setLoginTime(CommonUtils.getCurTimestamp());
        userLoginService.updateUserLogin(ulForUpdate);

        //token操作，登录成功并返回
        UserInfo userInfo = userInfoService.selectByUserID(userLogin.getUserID());

        /*if(Objects.equals(userInfo.getType(),2) && Objects.equals(userInfo.getIsAdmin(),1)){
            userInfo.setType(1);
        }*/
        if (userInfo.getIsStop() == 2) {
            throw new ServiceException("该账号审核中，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        if (userInfo.getIsStop() == 1) {
            throw new ServiceException("该账号已被停用，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        int userType = userInfo.getType();
        switch (type) {
            case 1:
                if (userType != 1 && userType != 2) {
                    throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
                }
                if (userInfo.getIsStop() == 2) {
                    throw new ServiceException("该账号尚未审核通过，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
                }
                break;
            case 2:
                if (userType != 5) {
                    throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
                }

                // 如果员工是店长，要置为普通员工，仅限Web
                if (1 == userInfo.getIsAdmin() && userInfo.getShopID() != null && userInfo.getShopID() != 0l) {
                    CompanyInfo companyInfo = companyInfoService.selectByPrimaryKey(userInfo.getShopID());
                    if (null != companyInfo && 2 == companyInfo.getType()) {
                        userInfo.setIsAdmin(2);
                    }
                }
                break;
            case 3:
                if (userInfo.getIsStop() == 2) {
                    throw new ServiceException("该账号尚未审核通过，请联系管理员", "006");
                }
                break;
            default:
                throw new ServiceException("type参数传入有误", RestConst.ErrorCode.FORM_FAIL);
        }
        //激活用户
        userInfoService.activeUser(userInfo);

        Integer recommenderPhone = null;
        if (userInfo.getType() == 2 || userInfo.getType() == 3) {
            recommenderPhone = userInfo.getRecommendNO();
        } else if (userInfo.getType() == 4) {
            UserInfo userInfoC = userInfoService.selectByUserID(userInfo.getPaterID());
            if (userInfoC != null) {
                recommenderPhone = userInfoC.getRecommendNO();
            }
        }

        //权限获取
        List<String> funCodeList = new ArrayList<>();
        if (userInfo.getType() == 1 || userInfo.getType() == 2) {
            funCodeList = userInfoService.getFunCodeByUserID(userLogin.getUserID());
        }
        String token = redisService.addOrUpdate(userInfo, loginDto, funCodeList);
        //组织ID及其名字
        Organizational organizational = organizationalService.selectByOID(userInfo.getOrganizationalID());
        if (organizational == null) {
            throw new ServiceException("未查到该用户的组织信息", RestConst.ErrorCode.DATABASE_ERROR);
        }
        int organizationalLevel = organizational.getLevel();
        String organizationalName = organizational.getOrganizationalName();

        UserInfoAndRoleList uiRoleList = new UserInfoAndRoleList();
        Long lastLoginTime;
        if (userLogin.getLoginTime() == null) {
            lastLoginTime = CommonUtils.getCurTimestamp();
        } else {
            lastLoginTime = userLogin.getLoginTime();
        }
        uiRoleList.setLastLoginIP(userLogin.getLoginIP());
        uiRoleList.setLastLoginTime(lastLoginTime);
        uiRoleList.setUserInfo(userInfo);
        uiRoleList.setOrganizationalLevel(organizationalLevel);
        uiRoleList.setOrganizationalName(organizationalName);
        uiRoleList.setRecommenderPhone(recommenderPhone);
        uiRoleList.setFunCodeList(funCodeList);

        JSONObject json = new JSONObject();
        if (userInfo.getType() == 5) {  //如果是供应商账号
            CompanyInfoVo companyInfo = companyInfoService.selectByUserID(userInfo.getUserID());
            if (companyInfo == null) {
                throw new ServiceException("供应商账户未查到供应商信息", RestConst.ErrorCode.SERVICE_LOGINERROR);
            }
            json.put("companyInfo", companyInfo);
        }
        json.put("userInfo", uiRoleList);
        json.put("token", token);
        if (type == 1) {
            if (userType == 1) {
                //如果密码还是初始密码888888，则前端跳转进修改密码界面
                if (loginDto.getPassWord().equals("5953e18651f662606261f8907d66bc34")) {
                    json.put("veriyPassWord", 1);
                } else {
                    json.put("veriyPassWord", 0);
                }
            } else {
                json.put("veriyPassWord", 0);
            }
        }
        logger.info(json);
        return json;
    }


    @ApiOperation(value = "获取rasKey")
    @RequestMapping(value = "/rasKey", method = RequestMethod.GET)
    public Object getRasKey() throws Exception {
        KeyPair keyPair = RSAUtils.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        RasKey rasKey = new RasKey();
        rasKey.setExponent(publicKey.getPublicExponent().toString(16));
        rasKey.setModulus(publicKey.getModulus().toString(16));
        rasKey.setRasId(UuidUtils.uuid());
        redisService.addOrUpdateRAS(rasKey.getRasId(), privateKey);
        return rasKey;
    }

    //云管控添加 系统管理员 销售经理
    @ApiOperation(value = "注册/添加[添加需要传添加人账户addUser]（type(1系统管理员，2销售经理，4会员)）")
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public Object register(@RequestBody RegisterDto registerDto) throws Exception {
        Object user = userInfoService.addUserInfoV2(registerDto);
        return user;
    }

    //h5商城会员
    @ApiOperation(value = "H5商城会员注册")
    @RequestMapping(value = "/jsRegister", method = RequestMethod.POST)
    public Object jsRegister(@RequestBody RegisterDto registerDto) throws Exception {
        verifyMobileCode(registerDto.getLoginName(), registerDto.getMobileCode());//验证验证码
        PrivateKey key = (PrivateKey) redisService.loadKey(registerDto.getRasId());
        byte[] en_result = RSAUtils.hexStringToBytes(registerDto.getPassWord());
        byte[] de_result = RSAUtils.decrypt(key, en_result);
        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.newStringUtf8(de_result));
        registerDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
        return userLoginService.register(registerDto);
    }

    @ApiOperation(value = "供应商注册[添加需要传添加人账户addUser]")
    @RequestMapping(value = "/supplierRegister", method = RequestMethod.POST)
    public Object supplierRegister(@RequestBody SupplierRegisterDto registerDto) throws Exception {
        //verifyImgCode(registerDto.getUuID(),registerDto.getImgCode()); //验证图形验证码
        if (registerDto.getCompanyInfo().getAddUser() != null && !registerDto.getCompanyInfo().getAddUser().equals("")) {
            UserInfo userInfo = userInfoService.selectByAccount(registerDto.getCompanyInfo().getAddUser(), SystemContext.getCompanyID());
            if (userInfo == null) {
                throw new ServiceException("未查到添加人信息，无权操作", RestConst.ErrorCode.FORM_FAIL);
            }
            if (userInfo.getType() != 1 && userInfo.getType() != 2) {
                throw new ServiceException("添加人没有权限进行操作", RestConst.ErrorCode.FORM_FAIL);
            }
            registerDto.getCompanyInfo().setIsAudit(1);   //添加直接通过审核
        } else {
            verifyMobileCode(registerDto.getCompanyInfo().getContactPhone(), registerDto.getMobileCode()); //验证手机验证码
            registerDto.getCompanyInfo().setIsAudit(0);   //注册默认未审核
        }
        PrivateKey key = (PrivateKey) redisService.loadKey(registerDto.getRasId());
        byte[] en_result = RSAUtils.hexStringToBytes(registerDto.getPassWord());
        byte[] de_result = RSAUtils.decrypt(key, en_result);
        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.newStringUtf8(de_result));
        registerDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
        return companyInfoService.registerCompanyInfo(registerDto);
    }


    @ApiOperation(value = "店铺添加[添加需要传添加人账户addUser]")
    @RequestMapping(value = "/shopRegister", method = RequestMethod.POST)
    public Object shopRegister(@RequestBody SupplierRegisterDto registerDto) throws Exception {
        if (registerDto.getCompanyInfo().getAddUser() != null && !registerDto.getCompanyInfo().getAddUser().equals("")) {
            UserInfo userInfo = userInfoService.selectByAccount(registerDto.getCompanyInfo().getAddUser(), SystemContext.getCompanyID());
            if (userInfo == null) {
                throw new ServiceException("未查到添加人信息，无权操作", RestConst.ErrorCode.FORM_FAIL);
            }
            if (userInfo.getType() != 1 && userInfo.getType() != 2) {
                throw new ServiceException("添加人没有权限进行操作", RestConst.ErrorCode.FORM_FAIL);
            }
            registerDto.getCompanyInfo().setIsAudit(1);   //添加直接通过审核
        } else {
            // verifyMobileCode(registerDto.getCompanyInfo().getContactPhone(), registerDto.getMobileCode()); //验证手机验证码
            registerDto.getCompanyInfo().setIsAudit(1);   //注册默认未审核
        }
//        PrivateKey key = (PrivateKey) redisService.loadKey(registerDto.getRasId());
//        byte[] en_result = RSAUtils.hexStringToBytes(registerDto.getPassWord());
//        byte[] de_result = RSAUtils.decrypt(key, en_result);
//        StringBuffer sb = new StringBuffer();
//        sb.append(StringUtils.newStringUtf8(de_result));
//        registerDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
//

        return companyInfoService.registerShopInfo(registerDto);
    }


    @ApiOperation(value = "店铺修改")
    @RequestMapping(value = "/shopUpdate", method = RequestMethod.POST)
    public Object shopUpdate(@RequestBody SupplierRegisterDto registerDto) throws Exception {
        return companyInfoService.updateShopInfo(registerDto);
    }


    @ApiOperation(value = "app注册")
    @RequestMapping(value = "/appRegister", method = RequestMethod.POST)
    public Object appRegister(@RequestBody RegisterDto registerDto) throws Exception {
        verifyMobileCode(registerDto.getLoginName(), registerDto.getMobileCode());//验证验证码
        String passWord = decryptByApp(registerDto);
        registerDto.setPassWord(CommonUtils.MD5(passWord));
        return userLoginService.register(registerDto);
    }

    @ApiOperation(value = "验证手机号（推荐人、本人）(0本人手机号已存在，1本人手机号不存在)")
    @RequestMapping(value = "/verifyPhone/{recommenderPhone}/{phone}", method = RequestMethod.GET)
    public Object verifyPhone(@PathVariable Integer recommenderPhone, @PathVariable String phone) throws Exception {
        if (recommenderPhone != 1) {
            UserInfo userInfo = userInfoService.selectByRecommendNO(recommenderPhone);
            if (userInfo == null) {
                throw new ServiceException("推荐码不存在", RestConst.ErrorCode.FORM_FAIL);
            }
        }
        return userLoginService.selectLoginName(phone);  //本人手机号（0已存在，1不存在）
    }

    @ApiOperation(value = "登录名验证（登录名or手机号）(0已存在，1不存在)")
    @RequestMapping(value = "/loginVerify/{loginName}", method = RequestMethod.GET)
    public Object loginVerify(@PathVariable String loginName) {
        return userLoginService.selectLoginName(loginName);  //手机号（0已存在，1不存在）
    }

    @ApiOperation(value = "登录名验证（登录名or手机号）(0已存在，1不存在,2已存在待完善资料)")
    @RequestMapping(value = "/loginVerify/{loginName}/{type}", method = RequestMethod.GET)
    public Object loginVerify2(@PathVariable String loginName, @PathVariable Integer type) {
        return userLoginService.selectLoginName2(loginName, type);  //手机号（0已存在，1不存在）
    }


    @ApiOperation(value = "供应商手机号验证(手机号）(0已存在，1不存在)")
    @RequestMapping(value = "/supplierVerify/{contactPhone}", method = RequestMethod.GET)
    public Object supplierVerify(@PathVariable String contactPhone) {
        return companyInfoService.selectSupplierByPhone(contactPhone);
    }

    @ApiOperation(value = "登录名验证（登录名or手机号）(0已存在，1不存在)")
    @RequestMapping(value = "/loginVerifyPost", method = RequestMethod.POST)
    public Object loginVerifyPost(@RequestBody VerifyLoginNameDto verifyLoginNameDto) {
        return userLoginService.selectLoginName(verifyLoginNameDto.getLoginName());  //手机号（0已存在，1不存在）
    }

    @ApiOperation(value = "供应商公司名验证(0已存在，1不存在)")
    @RequestMapping(value = "/verifySupplier", method = RequestMethod.POST)
    public Object verifySupplier(@RequestBody List<String> companyName) {
        return companyInfoService.verifySupplier(companyName.get(0));  //手机号（0已存在，1不存在）
    }

    @ApiOperation(value = "退出登录")
    @RequestMapping(value = "/loginOut", method = RequestMethod.POST)
    public Object loginOut(@RequestParam String userID) {
        Object o = redisService.loadKey(userID);
        if (o == null || o == "") {
            return "2";
        } else {
            redisService.delete(userID);
            Object object = redisService.loadKey(userID);
            if (object == null || object == "") {
                return "1";
            } else {
                return "0";
            }
        }
    }

    @ApiOperation(value = "忘记密码，修改密码")
    @RequestMapping(value = "/passWord", method = RequestMethod.POST)
    public Object updatePassWord(@RequestBody LoginDto loginDto) throws Exception {
        PrivateKey key = (PrivateKey) redisService.loadKey(loginDto.getRasId());
        if (loginDto.getOldPassWord() != null && !"".equals(loginDto.getOldPassWord())) {
            LoginDto oldDto = new LoginDto();
            oldDto.setLoginName(loginDto.getLoginName());
            oldDto.setRasId(loginDto.getRasId());
            byte[] en_result = RSAUtils.hexStringToBytes(loginDto.getOldPassWord());
            byte[] de_result = RSAUtils.decrypt(key, en_result);
            StringBuffer sb = new StringBuffer();
            sb.append(StringUtils.newStringUtf8(de_result));
            oldDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
            UserLogin oldUser = new UserLogin();
            BeanUtils.copyProperties(oldUser, oldDto);
            oldUser = userLoginService.selectForLogin(oldUser);
            if (oldUser == null)
                throw new ServiceException("login error", RestConst.ErrorCode.SERVICE_LOGINERROR);
        } else {
            verifyMobileCode(loginDto.getLoginName(), loginDto.getMobileCode());
        }
        byte[] en_result = RSAUtils.hexStringToBytes(loginDto.getPassWord());
        byte[] de_result = RSAUtils.decrypt(key, en_result);
        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.newStringUtf8(de_result));
        String passWord = CommonUtils.MD5(sb.reverse().toString());
        loginDto.setPassWord(passWord);
        UserInfo userInfo = new UserInfo();
        //UserLogin user1 = new UserLogin();
        Long user1ID = null;
        if (CommonUtils.isNotEmpty(loginDto.getIsSupplier()) && "1".equals(loginDto.getIsSupplier())) {//供应商根据手机号查询userID
            user1ID = companyInfoService.selectSupplierInfoByPhone(loginDto.getLoginName()).getUserID();
        } else {
            user1ID = userLoginService.selectByLoginName(loginDto.getLoginName()).getUserID();
        }
        userInfo.setUserID(user1ID);
        userInfo.setPassWord(passWord);
        return userInfoService.updateUserInfo(userInfo, true);
    }


    /**
     * <-----------------------------------app端登录注册修改密码等--------------------------------------->
     */
    @ApiOperation(value = "app登录")
    @RequestMapping(value = "/appLogin", method = RequestMethod.POST)
    public Object appLogin(@RequestBody LoginDto loginDto) throws Exception {
        String passWord = decryptByApp(loginDto);
        loginDto.setPassWord(CommonUtils.MD5(passWord));
        UserLogin userLogin = new UserLogin();
        BeanUtils.copyProperties(userLogin, loginDto);
        if (userLogin.getLoginName() == null || userLogin.getPassWord() == null) {
            throw new ServiceException("登录名或密码不能为空", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        userLogin = userLoginService.selectForLogin(userLogin);
        if (userLogin == null) {
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        //修改登录表信息
        UserLogin ulForUpdate = new UserLogin();
        ulForUpdate.setId(userLogin.getId());
        ulForUpdate.setLastLoginIP(userLogin.getLoginIP());
        ulForUpdate.setLastLoginTime(userLogin.getLoginTime());
        ulForUpdate.setLoginIP(CusAccessObjectUtil.getIpAddress(request));
        ulForUpdate.setLoginTime(CommonUtils.getCurTimestamp());
        userLoginService.updateUserLogin(ulForUpdate);

        //token操作，登录成功并返回
        UserInfo userInfo = userInfoService.selectByUserID(userLogin.getUserID());

        if (userInfo.getIsStop() == 2) {
            throw new ServiceException("该账号尚未通过审核，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        if (userInfo.getIsStop() == 1) {
            throw new ServiceException("该账号已被停用，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        userInfoService.activeUser(userInfo);
        String token = redisService.addOrUpdate(userInfo, loginDto, null);

        //组织ID及其名字
        Organizational organizational = organizationalService.selectByOID(userInfo.getOrganizationalID());
        if (organizational == null) {
            throw new ServiceException("未查到该用户的组织信息", RestConst.ErrorCode.DATABASE_ERROR);
        }
        int organizationalLevel = organizational.getLevel();
        String organizationalName = organizational.getOrganizationalName();

        UserInfoAndRoleList uiRoleList = new UserInfoAndRoleList();

        Integer recommenderPhone = null;
        if (userInfo.getType() == 2 || userInfo.getType() == 3) {
            recommenderPhone = userInfo.getRecommendNO();
        } else if (userInfo.getType() == 4) {
            UserInfo userInfoC = userInfoService.selectByUserID(userInfo.getPaterID());
            if (userInfoC != null) {
                recommenderPhone = userInfoC.getRecommendNO();
            }
        }

        uiRoleList.setOrganizationalLevel(organizationalLevel);
        uiRoleList.setOrganizationalName(organizationalName);
        uiRoleList.setRecommenderPhone(recommenderPhone);
        uiRoleList.setUserInfo(userInfo);
        JSONObject json = new JSONObject();

        json.put("userInfo", uiRoleList);
        json.put("token", token);
        logger.info(json);
        return json;
    }

    @ApiOperation(value = "b2b登录")
    @RequestMapping(value = "/h5/b2b/login", method = RequestMethod.POST)
    public Object b2bLogin(@RequestBody LoginDto loginDto) throws Exception {
        PrivateKey key = (PrivateKey) redisService.loadKey(loginDto.getRasId());
        byte[] en_result = RSAUtils.hexStringToBytes(loginDto.getPassWord());
        byte[] de_result = RSAUtils.decrypt(key, en_result);
        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.newStringUtf8(de_result));
        loginDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
        UserLogin userLogin = new UserLogin();
        BeanUtils.copyProperties(userLogin, loginDto);
        userLogin = userLoginService.selectForLogin(userLogin);
        if (userLogin == null) {
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }

        //修改登录表信息
        UserLogin ulForUpdate = new UserLogin();
        ulForUpdate.setId(userLogin.getId());
        ulForUpdate.setLastLoginIP(userLogin.getLoginIP());
        ulForUpdate.setLastLoginTime(userLogin.getLoginTime());
        ulForUpdate.setLoginIP(CusAccessObjectUtil.getIpAddress(request));
        ulForUpdate.setLoginTime(CommonUtils.getCurTimestamp());
        userLoginService.updateUserLogin(ulForUpdate);

        //token操作，登录成功并返回
        UserInfo userInfo = userInfoService.selectByUserID(userLogin.getUserID());


        int userType = userInfo.getType();
        /*if(!Objects.equal(userType,6)){
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }*/
       /* if (userInfo.getIsStop() == 2 && !Objects.equal(userInfo.getType(),6)) {
            throw new ServiceException("该账号尚未通过审核，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }*/
        if (Objects.equal(userType, 5)) {//供应商不能登
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        if (userInfo.getIsStop() == 2) {
            if (Objects.equal(userInfo.getType(), 6)) {
                throw new ServiceException("资料正在审核中，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
            } else {
                throw new ServiceException("该账号尚未通过审核，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
            }
        }
        if (userInfo.getIsStop() == 1) {
            throw new ServiceException("该账号已被停用，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        //激活用户
        userInfoService.activeUser(userInfo);

        //权限获取
        List<String> funCodeList = new ArrayList<>();
        if (userInfo.getType() == 1 || userInfo.getType() == 2) {
            funCodeList = userInfoService.getFunCodeByUserID(userLogin.getUserID());
        }
        String token = redisService.addOrUpdate(userInfo, loginDto, funCodeList);
        //组织ID及其名字
        Organizational organizational = organizationalService.selectByOID(userInfo.getOrganizationalID());
        if (organizational == null) {
            throw new ServiceException("未查到该用户的组织信息", RestConst.ErrorCode.DATABASE_ERROR);
        }
        int organizationalLevel = organizational.getLevel();
        String organizationalName = organizational.getOrganizationalName();

        UserInfoAndRoleList uiRoleList = new UserInfoAndRoleList();
        Long lastLoginTime;
        if (userLogin.getLoginTime() == null) {
            lastLoginTime = CommonUtils.getCurTimestamp();
        } else {
            lastLoginTime = userLogin.getLoginTime();
        }
        uiRoleList.setLastLoginIP(userLogin.getLoginIP());
        uiRoleList.setLastLoginTime(lastLoginTime);
        uiRoleList.setUserInfo(userInfo);
        uiRoleList.setOrganizationalLevel(organizationalLevel);
        uiRoleList.setOrganizationalName(organizationalName);
        //uiRoleList.setRecommenderPhone(recommenderPhone);
        uiRoleList.setFunCodeList(funCodeList);

        JSONObject json = new JSONObject();
        if (userInfo.getType() == 6) {  //如果是采购商
            CompanyInfo companyInfo = companyInfoService.selectByUserID2(userInfo.getUserID());
            if (companyInfo == null) {
                //throw new ServiceException("供应商账户未查到供应商信息", RestConst.ErrorCode.SERVICE_LOGINERROR);
                uiRoleList.setIsAudit(0);//是否审核 0未审核 1通过 2失败
            } else {
                uiRoleList.setIsAudit(companyInfo.getIsAudit());//是否审核 0未审核 1通过 2失败
            }
        } else {
            uiRoleList.setIsAudit(1);
        }
        json.put("userInfo", uiRoleList);
        json.put("token", token);
        logger.info(json);
        return json;
    }


    @ApiOperation(value = "app登录")
    @RequestMapping(value = "/b2b/appLogin", method = RequestMethod.POST)
    public Object appLoginForB2b(@RequestBody LoginDto loginDto) throws Exception {
        String passWord = decryptByApp(loginDto);
        loginDto.setPassWord(CommonUtils.MD5(passWord));
        UserLogin userLogin = new UserLogin();
        BeanUtils.copyProperties(userLogin, loginDto);
        if (userLogin.getLoginName() == null || userLogin.getPassWord() == null) {
            throw new ServiceException("登录名或密码不能为空", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        userLogin = userLoginService.selectForLogin(userLogin);
        if (userLogin == null) {
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        //修改登录表信息
        UserLogin ulForUpdate = new UserLogin();
        ulForUpdate.setId(userLogin.getId());
        ulForUpdate.setLastLoginIP(userLogin.getLoginIP());
        ulForUpdate.setLastLoginTime(userLogin.getLoginTime());
        ulForUpdate.setLoginIP(CusAccessObjectUtil.getIpAddress(request));
        ulForUpdate.setLoginTime(CommonUtils.getCurTimestamp());
        userLoginService.updateUserLogin(ulForUpdate);

        //token操作，登录成功并返回
        UserInfo userInfo = userInfoService.selectByUserID(userLogin.getUserID());

        //只给采购商登录
        /*if(!Objects.equal(userInfo.getType(),6)){
            throw new ServiceException("用户名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }*/
       /* if (userInfo.getIsStop() == 2 && !Objects.equal(userInfo.getType(),6)) {
            throw new ServiceException("该账号尚未通过审核，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }*/
        Integer userType = userInfo.getType();
        if (Objects.equal(userType, 5)) {//供应商不能登
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        if (userInfo.getIsStop() == 2) {
            if (Objects.equal(userInfo.getType(), 6)) {
                throw new ServiceException("资料正在审核中，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
            } else {
                throw new ServiceException("该账号尚未通过审核，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
            }
        }
        if (userInfo.getIsStop() == 1) {
            throw new ServiceException("该账号已被停用，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        userInfoService.activeUser(userInfo);
        String token = redisService.addOrUpdate(userInfo, loginDto, null);

        //组织ID及其名字
        Organizational organizational = organizationalService.selectByOID(userInfo.getOrganizationalID());
        if (organizational == null) {
            throw new ServiceException("未查到该用户的组织信息", RestConst.ErrorCode.DATABASE_ERROR);
        }
        int organizationalLevel = organizational.getLevel();
        String organizationalName = organizational.getOrganizationalName();

        UserInfoAndRoleList uiRoleList = new UserInfoAndRoleList();

        Integer recommenderPhone = null;
        if (userInfo.getType() == 2 || userInfo.getType() == 3) {
            recommenderPhone = userInfo.getRecommendNO();
        } else if (userInfo.getType() == 4) {
            UserInfo userInfoC = userInfoService.selectByUserID(userInfo.getPaterID());
            if (userInfoC != null) {
                recommenderPhone = userInfoC.getRecommendNO();
            }
        }

        uiRoleList.setOrganizationalLevel(organizationalLevel);
        uiRoleList.setOrganizationalName(organizationalName);
        uiRoleList.setRecommenderPhone(recommenderPhone);
        uiRoleList.setUserInfo(userInfo);
        JSONObject json = new JSONObject();
        if (userInfo.getType() == 6) {  //如果是采购商
            CompanyInfo companyInfo = companyInfoService.selectByUserID2(userInfo.getUserID());
            if (companyInfo == null) {
                //throw new ServiceException("供应商账户未查到供应商信息", RestConst.ErrorCode.SERVICE_LOGINERROR);
                uiRoleList.setIsAudit(0);//是否审核 0未审核 1通过 2失败
            } else {
                uiRoleList.setIsAudit(companyInfo.getIsAudit());//是否审核 0未审核 1通过 2失败
            }
        } else {
            uiRoleList.setIsAudit(1);
        }
        json.put("userInfo", uiRoleList);
        json.put("token", token);
        logger.info(json);
        return json;
    }


    @ApiOperation(value = "app端rasKey获取")
    @RequestMapping(value = "/appKey", method = RequestMethod.GET)
    @ResponseBody
    public Object getappKey() throws Exception {
        Map map = AppRSAUtils.genKeyPair();
        Key publicKey = (Key) map.get(AppRSAUtils.PUBLIC_KEY);
        Key privateKey = (Key) map.get(AppRSAUtils.PRIVATE_KEY);
        String publicKeyStr = Base64Utils.encode(publicKey.getEncoded());
        String privateKeyStr = Base64Utils.encode(privateKey.getEncoded());
        RasKey rasKey = new RasKey();
        rasKey.setExponent(publicKeyStr);
        rasKey.setModulus("");
        rasKey.setRasId(UuidUtils.uuid());
        redisService.addOrUpdateRAS(rasKey.getRasId(), privateKeyStr);
        return rasKey;
    }

    @ApiOperation(value = "app端忘记密码，修改密码")
    @RequestMapping(value = "/appPassWord", method = RequestMethod.POST)
    public Object updateAppPassWord(@RequestBody LoginDto loginDto) throws Exception {
        if (loginDto.getOldPassWord() != null && !"".equals(loginDto.getOldPassWord())) {
            LoginDto oldDto = new LoginDto();
            oldDto.setLoginName(loginDto.getLoginName());
            oldDto.setPassWord(loginDto.getOldPassWord());
            oldDto.setRasId(loginDto.getRasId());
            String oldPassWord = decryptByApp(loginDto);
            oldDto.setPassWord(CommonUtils.MD5(oldPassWord));
            UserLogin oldUser = new UserLogin();
            BeanUtils.copyProperties(oldUser, oldDto);
            oldUser = userLoginService.selectForLogin(oldUser);
            if (oldUser == null)
                throw new ServiceException("login error", RestConst.ErrorCode.SERVICE_LOGINERROR);
        } else {
            verifyMobileCode(loginDto.getLoginName(), loginDto.getMobileCode());
        }
        String passWord = decryptByApp(loginDto);
        UserLogin user1 = userLoginService.selectByLoginName(loginDto.getLoginName());
        UserInfo userInfo = userInfoService.selectByUserID(user1.getUserID());
        userInfo.setPassWord(CommonUtils.MD5(passWord));
        userInfoService.updateUserInfo(userInfo, true);
        return "success";
    }


    @ApiOperation(value = "验证手机验证码")
    @RequestMapping(value = "/verifySMSCode/{mobile}/{code}", method = RequestMethod.GET)
    public Object verifySMSCode(@PathVariable String mobile, @PathVariable String code) {
        return verifyMobileCode(mobile, code);
    }

    @ApiOperation(value = "临时发送通知短信")
    @RequestMapping(value = "/sendSMSNoticeTemp/{mobile}/{tempId}/{param}", method = RequestMethod.GET)
    @ApiImplicitParams({@ApiImplicitParam(paramType = "path", name = "mobile", required = true, value = "接收短信的三网手机号", defaultValue = "13798185456"),
            @ApiImplicitParam(paramType = "path", name = "tempId", required = true, value = "阿里大于通知短信模版号", defaultValue = "SMS_66560273"),
            @ApiImplicitParam(paramType = "path", name = "param", required = false, value = "参数值，多个用逗号隔开", defaultValue = "2017年5月20号")})

    public Object sendSMSTemp(@PathVariable String mobile, @PathVariable String type, @PathVariable String param) {

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("mobile", mobile); //下单人手机
        jsonObject.put("type", type);

        String[] temp = new String[]{};
        if (!"{param}".equalsIgnoreCase(param)) {
            temp = param.split(",");
        }
        jsonObject.put("param", temp);
        DataResult result = HttpUtil.httpPost(ProConstants.SMS + "/notice", jsonObject, restTemplate);
        if (result.getIsSuccess() != 1) {
            logger.error("调用短信服务失败:" + result.getErrorDesc());
        }
        return "success";
    }

    @ApiOperation(value = "代办事项权限 TO APP商户通")
    @RequestMapping(value = "/toDoTipsAuthority/{userID}", method = RequestMethod.GET)
    @ApiImplicitParams({@ApiImplicitParam(paramType = "path", name = "userID", required = true, value = "", defaultValue = "13798185456")})
    public Object toDoTipsAuthority(@PathVariable Long userID) {
        List<String> funCodeList = new ArrayList<>();
        UserInfo userInfo = userInfoService.selectByUserID(userID);
        if (userInfo.getType() == 1 || userInfo.getType() == 2) {
            funCodeList = userInfoService.getFunCodeByUserID(userInfo.getUserID());
        }

        Config config = (Config) configService.getConfigByID(SystemContext.getCompanyID());
        Map<String, Object> map = new HashMap();
        map.put("fun", funCodeList);
        map.put("config", config);
        //map.put("userInfo",userInfo);
        return map;
    }

    @ApiOperation(value = "微信授权登录(会员顾问)")
    @RequestMapping(value = "/wxlogin", method = RequestMethod.POST)
    public Object loginWechat(@RequestBody LoginDto loginDto) throws Exception {
        int type = 3;
        UserLogin userLogin = new UserLogin();
        BeanUtils.copyProperties(userLogin, loginDto);
        userLogin = userLoginService.selectForLogin(userLogin);
        if (userLogin == null) {
            throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }

        //修改登录表信息
        UserLogin ulForUpdate = new UserLogin();
        ulForUpdate.setId(userLogin.getId());
        ulForUpdate.setLastLoginIP(userLogin.getLoginIP());
        ulForUpdate.setLastLoginTime(userLogin.getLoginTime());
        ulForUpdate.setLoginIP(CusAccessObjectUtil.getIpAddress(request));
        ulForUpdate.setLoginTime(CommonUtils.getCurTimestamp());
        userLoginService.updateUserLogin(ulForUpdate);

        //token操作，登录成功并返回
        UserInfo userInfo = userInfoService.selectByUserID(userLogin.getUserID());

        if (userInfo.getIsStop() == 2) {
            throw new ServiceException("该账号审核中，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        if (userInfo.getIsStop() == 1) {
            throw new ServiceException("该账号已被停用，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
        int userType = userInfo.getType();
        switch (type) {
            case 1:
                if (userType != 1 && userType != 2) {
                    throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
                }
                if (userInfo.getIsStop() == 2) {
                    throw new ServiceException("该账号尚未审核通过，请联系管理员", RestConst.ErrorCode.SERVICE_LOGINERROR);
                }
                break;
            case 2:
                if (userType != 5) {
                    throw new ServiceException("登录名或密码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
                }

                // 如果员工是店长，要置为普通员工，仅限Web
                if (1 == userInfo.getIsAdmin() && userInfo.getShopID() != null && userInfo.getShopID() != 0l) {
                    CompanyInfo companyInfo = companyInfoService.selectByPrimaryKey(userInfo.getShopID());
                    if (null != companyInfo && 2 == companyInfo.getType()) {
                        userInfo.setIsAdmin(2);
                    }
                }
                break;
            case 3:
                if (userInfo.getIsStop() == 2) {
                    throw new ServiceException("该账号尚未审核通过，请联系管理员", "006");
                }
                break;
            default:
                throw new ServiceException("type参数传入有误", RestConst.ErrorCode.FORM_FAIL);
        }
        //激活用户
        userInfoService.activeUser(userInfo);

        Integer recommenderPhone = null;
        if (userInfo.getType() == 2 || userInfo.getType() == 3) {
            recommenderPhone = userInfo.getRecommendNO();
        } else if (userInfo.getType() == 4) {
            UserInfo userInfoC = userInfoService.selectByUserID(userInfo.getPaterID());
            if (userInfoC != null) {
                recommenderPhone = userInfoC.getRecommendNO();
            }
        }

        //权限获取
        List<String> funCodeList = new ArrayList<>();
        if (userInfo.getType() == 1 || userInfo.getType() == 2) {
            funCodeList = userInfoService.getFunCodeByUserID(userLogin.getUserID());
        }
        String token = redisService.addOrUpdate(userInfo, loginDto, funCodeList);
        //组织ID及其名字
        Organizational organizational = organizationalService.selectByOID(userInfo.getOrganizationalID());
        if (organizational == null) {
            throw new ServiceException("未查到该用户的组织信息", RestConst.ErrorCode.DATABASE_ERROR);
        }
        int organizationalLevel = organizational.getLevel();
        String organizationalName = organizational.getOrganizationalName();

        UserInfoAndRoleList uiRoleList = new UserInfoAndRoleList();
        Long lastLoginTime;
        if (userLogin.getLoginTime() == null) {
            lastLoginTime = CommonUtils.getCurTimestamp();
        } else {
            lastLoginTime = userLogin.getLoginTime();
        }
        uiRoleList.setLastLoginIP(userLogin.getLoginIP());
        uiRoleList.setLastLoginTime(lastLoginTime);
        uiRoleList.setUserInfo(userInfo);
        uiRoleList.setOrganizationalLevel(organizationalLevel);
        uiRoleList.setOrganizationalName(organizationalName);
        uiRoleList.setRecommenderPhone(recommenderPhone);
        uiRoleList.setFunCodeList(funCodeList);

        JSONObject json = new JSONObject();
        if (userInfo.getType() == 5) {  //如果是供应商账号
            CompanyInfoVo companyInfo = companyInfoService.selectByUserID(userInfo.getUserID());
            if (companyInfo == null) {
                throw new ServiceException("供应商账户未查到供应商信息", RestConst.ErrorCode.SERVICE_LOGINERROR);
            }
            json.put("companyInfo", companyInfo);
        }
        json.put("userInfo", uiRoleList);
        json.put("token", token);
        if (type == 1) {
            if (userType == 1) {
                //如果密码还是初始密码888888，则前端跳转进修改密码界面
                if (loginDto.getPassWord().equals("5953e18651f662606261f8907d66bc34")) {
                    json.put("veriyPassWord", 1);
                } else {
                    json.put("veriyPassWord", 0);
                }
            } else {
                json.put("veriyPassWord", 0);
            }
        }
        logger.info(json);
        return json;
    }


    /**
     * 验证手机验证码
     */
    private Object verifyMobileCode(String mobile, String code) {
        String url = codeUrl + mobile;
        JSONObject json = restTemplate.getForObject(url, JSONObject.class);
        if (json.size() == 0) {
            throw new ServiceException("手机验证码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        } else {
            String getCode = json.get(mobile).toString();
            if (!code.equals(getCode)) {
                throw new ServiceException("手机验证码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
            }
        }

        return 1;
    }

    /**
     * 验证图形验证码
     */
    private void verifyImgCode(String uuID, String code) {
        String getCode = codeService.verificationCode(uuID, code);
        if (getCode.equals("0")) {
            throw new ServiceException("图形验证码错误", RestConst.ErrorCode.SERVICE_LOGINERROR);
        }
    }

    private String decryptByApp(LoginDto loginDto) throws Exception {
        String privateKey = (String) redisService.loadKey(loginDto.getRasId());
        byte[] decodedData = AppRSAUtils.decryptByPrivateKey(Base64Utils.decode(loginDto.getPassWord()), privateKey);
        return new String(decodedData);
    }
}
